package com.lzkjiot.service.gnss.transger.core.server;

import com.lzkjiot.service.gnss.transger.core.DataInFrame;
import com.lzkjiot.service.gnss.transger.core.constants.NettyConstants;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

import java.util.List;

/**
 * @author King
 * @date 2021/7/14
 */
public class DataFrameDecoder extends ByteToMessageDecoder {

    /*
     *    包头        设备id    数据类型    数据长度    工况数据长度      数据      crc（校验和）
     *   2 字节       4字节     2字节       2字节         2字节                   2字节
     * 0x22 0x33     端口号     后8位                    后八位
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        in.readBytes(2);    //帧头 0x22 0x33
        // 设备编码 4字节  前面16位保留，后面16位取值范围0-65535
        in.readBytes(2);    //设备地址前16位 预留
        int deviceId = in.readUnsignedShortLE();
        // channel attr<deviceId> 设置
        String attrDeviceId = ctx.channel().attr(NettyConstants.DEVICE_ID).get();
        if(attrDeviceId == null){
            ctx.channel().attr(NettyConstants.DEVICE_ID).set(String.valueOf(deviceId));
        }
        // 数据类型
        in.readBytes(2); // 数据类型  保留字节
        // 长度位
        int length = in.readUnsignedShortLE();        // 载体总长度 = 工况数据长度位（2字节） + 工况数据长度  + gnss数据
        int conditionLength = in.readUnsignedShortLE();   // 工况数据长度
        // 读取工况数据
        byte[] conditionData = new byte[conditionLength];
        in.readBytes(conditionData);
        // GNSS观测数据
        byte[] gnssData = new byte[length - conditionLength - 2];
        in.readBytes(gnssData);
        short crc = in.readShort();        // 和校验
//        System.out.println("校验位："+ByteBufUtil.hexDump(in.readBytes(2)));
        DataInFrame dataInFrame = new DataInFrame(deviceId, gnssData, conditionData);
//         将解析后的数据加入到list中,传递给后续的channelHandler
        out.add(dataInFrame);
    }

    public static String byteBufToHex(ByteBuf byteBuf) {
        StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < byteBuf.readableBytes(); i++) {
            // 将每个字节格式化为 16 进制字符串并追加到 StringBuilder
            hexString.append(String.format("%02X ", byteBuf.getByte(i)));
        }
        return hexString.toString().trim(); // 去除最后的空格
    }

    public static void main(String[] args) {
        ByteBuf originalBuf = Unpooled.buffer();
        originalBuf.writeBytes(new byte[] { 0x1E, (byte) 0xEC});
        System.out.println(byteBufToHex(originalBuf));
        System.out.println(originalBuf.readUnsignedShortLE());
    }
}
